#include <stdio.h>
#include <err.h>
#include <string.h>

#include <json/json.h>

#include <curl/curl.h>


#define SZ_AUTH_STR_BUF 255

typedef struct {
  char *ptr;
  size_t len;
} char_buf_t;


typedef struct {
    const char* cookie;
    const char* pub_ip;
} ddns_context_t;

ddns_context_t g_ctx;
char g_auth_buf[SZ_AUTH_STR_BUF];

void init_buf(char_buf_t *s) {
  s->len = 0;
  s->ptr = NULL;
}

size_t writefunc(void *ptr, size_t size, size_t nmemb, char_buf_t *s)
{
  size_t len = size*nmemb;
  s->ptr = malloc(len+1);
  if (s->ptr == NULL) {
    fprintf(stderr, "malloc() failed\n");
    exit(EXIT_FAILURE);
  }
  memcpy(s->ptr, ptr, len);
  s->ptr[len] = '\0';
  s->len = len;

  return len;
}

char* curl_https_get(const char* url, const char* cookie)
{
    CURL * curl;
    CURLcode res;
    char* res_str = NULL;

    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    if (curl) {
        struct curl_slist *chunk = NULL;
     
        chunk = curl_slist_append(chunk, "application/json");
        char_buf_t s;
        init_buf(&s);

        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);

        if(cookie != NULL)
        {
            curl_easy_setopt(curl, CURLOPT_COOKIE, cookie);
        }

        res = curl_easy_perform(curl);
        if(res != CURLE_OK) {
              fprintf(stderr, "curl_easy_perform() failed: %s\n",
                curl_easy_strerror(res));
        }
        else {
            //printf("HTTP RESP:%s\n",s.ptr);
            res_str = s.ptr;
        }

        curl_easy_cleanup(curl);
        
    }
    curl_global_cleanup();
    return res_str;
}


const char* get_auth_string_by_json_rsp(const char * jstr)
{
    const char* auth_string;
    json_object * jobj = json_tokener_parse(jstr);
    if(json_object_get_type(jobj) != json_type_object)
    {
        return NULL;
    }

    jobj = json_object_object_get(jobj,"mario");

    if ( (jobj == NULL) || 
         (json_object_get_type(jobj) != json_type_string)
       )
    {
        return NULL;
    }
    auth_string =  json_object_get_string(jobj);
    static const char * k = "mario=";
    memcpy(g_auth_buf,k,strlen(k));
    memcpy(g_auth_buf+strlen(k), auth_string, strlen(auth_string));
    memset(g_auth_buf+strlen(k)+strlen(auth_string),'\0',1);

    return g_auth_buf;
}

int test_json() 
{
   const char *tstr= "{ \"mario\": \"test@test.it,1,2012-04-28T05:21:17,0d12d$31cc2cb09b29e2aebb4587d34918a0d\" }";
   const char * auth_str= get_auth_string_by_json_rsp(tstr);
   printf ("AUTH string: %s\n", auth_str);
   return 0;
}

void http_cmd(const char* url, const char* cookie, void (*func)(const char* )) 
{
    char* http_res = curl_https_get(url, cookie);
    func(http_res);
    //free(http_res);
}


void cb_auth_string(const char* http_res) 
{
    g_ctx.cookie= get_auth_string_by_json_rsp(http_res);
    printf("g auth string: %s\n", g_ctx.cookie);
}

void cb_pub_ip(const char* http_res)
{
   g_ctx.pub_ip = http_res; 
   printf("PUB ip: %s\n", http_res);
}

void cb_print(const char* http_res)
{
    printf("HTTP RES: %s\n", http_res);
}

int main() {
   memset(&g_ctx,0,sizeof(g_ctx));

   const char * auth_req_url  = "https://www.dnspod.com/api/auth?email=westfox@gmail.com&password=tkxj125";
   http_cmd(auth_req_url, NULL, cb_auth_string);

    /**
    curl -H 'application/json' -X GET 'https://www.dnspod.com/api/domains?group=__all__&start=0&end=2' -b 'mario=test@test.it,1,2012-04-28T05:21:17,0d12d$31cc2cb09b29e2ae2bb4587d34918a0d'
    **/

   if(strlen(g_ctx.cookie) > 0)
   {
        const char *get_domain_url = "https://www.dnspod.com/api/domains?group=__all__&start=0&end=2";
        http_cmd(get_domain_url, g_ctx.cookie, cb_print);
        
        http_cmd("ipecho.net/plain",NULL, cb_pub_ip);

        http_cmd("https://www.dnspod.com/api/records/obsd55.ml", g_ctx.cookie, cb_print);

   }

   return 0;
}

